/*
 * _______________#########_______________________ 
 * ______________############_____________________ 
 * ______________#############____________________ 
 * _____________##__###########___________________ 
 * ____________###__######_#####__________________ 
 * ____________###_#######___####_________________ 
 * ___________###__##########_####________________ 
 * __________####__###########_####_______________ 
 * ________#####___###########__#####_____________ 
 * _______######___###_########___#####___________ 
 * _______#####___###___########___######_________ 
 * ______######___###__###########___######_______ 
 * _____######___####_##############__######______ 
 * ____#######__#####################_#######_____ 
 * ____#######__##############################____ 
 * ___#######__######_#################_#######___ 
 * ___#######__######_######_#########___######___ 
 * ___#######____##__######___######_____######___ 
 * ___#######________######____#####_____#####____ 
 * ____######________#####_____#####_____####_____ 
 * _____#####________####______#####_____###______ 
 * ______#####______;###________###______#________ 
 * ________##_______####________####______________ 
 * 
 * @Author: ipk518 18163976442@163.com
 * @Date: 2024-09-03 16:04:48
 * @LastEditors: ipk518 18163976442@163.com
 * @LastEditTime: 2024-12-10 15:33:25
 * @FilePath: /etws-sxk2307/tools/qsfp/main.c
 * @Description: 
 * ************佛祖保佑************
 * Copyright (c) 2024 by etws@quyujiang, All Rights Reserved. 
 */

#include "qsfp.h"
#include <string.h>
#include <unistd.h>

struct qsfp_12x_Txcache m_x12tx;
struct qsfp_12x_Rxcache m_x12rx;
struct qsfp_4x_cache m_x4Cache;
struct upperMemory00h m_upperMemory00h;
struct upperMemoryTx1 m_x12txUpper;
struct upperMemoryRx1 m_x12rxUpper;


#define QLOG_LINE_BUF_SIZE 256
#define QLOG_NEWLINE_SIGN "\n"
/**
 * another copy string function
 *
 * @param cur_len current copied log length, max size is ELOG_LINE_BUF_SIZE
 * @param dst destination
 * @param src source
 *
 * @return copied length
 */
static size_t qlog_strcpy(size_t cur_len, char *dst, const char *src) {
    const char *src_old = src;

    // assert(dst);
    // assert(src);

    while (*src != 0) {
        /* make sure destination has enough space */
        if (cur_len++ < QLOG_LINE_BUF_SIZE) {
            *dst++ = *src++;
        } else {
            break;
        }
    }
    return src - src_old;
}
/**
 * @brief: 输出指定长度的数组数据
 * @param {const char *} name 本次输出的名称
 * @param {uint8} width：指定输出的宽度，多少个字节一行
 * @param {uint8} buf：需要输出的数据
 * @param {uint16} size：需要输出的长度
 * @return {*}
 */

void qlog_hexdump(const char *name, uint8_t width, uint8_t *buf, uint16_t size)
{
#define __is_print(ch)       ((unsigned int)((ch) - ' ') < 127u - ' ')


    uint16_t i, j;
    uint16_t log_len = 0;
    char dump_string[8] = {0};
    int fmt_result;
    static char log_buf[QLOG_LINE_BUF_SIZE];

    for (i = 0; i < size; i += width) {
        /* package header */
        fmt_result = snprintf(log_buf, QLOG_LINE_BUF_SIZE, "D/HEX %s: %04X-%04X: ", name, i, i + width - 1);
        /* calculate log length */
        if ((fmt_result > -1) && (fmt_result <= QLOG_LINE_BUF_SIZE)) {
            log_len = fmt_result;
        } else {
            log_len = QLOG_LINE_BUF_SIZE;
        }
        /* dump hex */
        for (j = 0; j < width; j++) {
            if (i + j < size) {
                snprintf(dump_string, sizeof(dump_string), "%02X ", buf[i + j]);
            } else {
                strncpy(dump_string, "   ", sizeof(dump_string));
            }
            log_len += qlog_strcpy(log_len, log_buf + log_len, dump_string);
            if ((j + 1) % 8 == 0) {
                log_len += qlog_strcpy(log_len, log_buf + log_len, " ");
            }
        }
        log_len += qlog_strcpy(log_len, log_buf + log_len, "  ");
        /* dump char for hex */
        for (j = 0; j < width; j++) {
            if (i + j < size) {
                snprintf(dump_string, sizeof(dump_string), "%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
                log_len += qlog_strcpy(log_len, log_buf + log_len, dump_string);
            }
        }
        /* overflow check and reserve some space for newline sign */
        if (log_len + strlen(QLOG_NEWLINE_SIGN) > QLOG_LINE_BUF_SIZE) {
            log_len = QLOG_LINE_BUF_SIZE - strlen(QLOG_NEWLINE_SIGN);
        }
        /* package newline sign */
        log_len += qlog_strcpy(log_len, log_buf + log_len, QLOG_NEWLINE_SIGN);
        /* do log output */
        printf("%s",log_buf);
    }

}

#define DEV_SUCCESS 0

int main(int argc, char *argv[])
{
    int ret = 0;
    // 初始化QSFP设备
    int init4xFlag = qsfp_4x_init();
    int init12xFlag = qsfp_12x_init();
    init12xFlag = -1;
    uint8_t m_txdata[256];
    uint8_t m_rxdata[256];
    while(1)
    {
        if(init4xFlag == DEV_SUCCESS) {
            refresh_qsfp_4x_cache(&m_x4Cache);
            sleep(1);
            refresh_qsfp_4x_upperMemory();

            memcpy((uint8_t *)&m_upperMemory00h,m_qsfp_4x_upper[0],sizeof(m_upperMemory00h));

            printf("4x Device Tech:%d\n",m_upperMemory00h.m_devTech);
            printf("4x Vendor name:%s\n",m_upperMemory00h.m_vendorName);
            printf("4x Vendor PN:%s\n",m_upperMemory00h.m_vendorPN);
            printf("4x Vendor Rev:%s\n",m_upperMemory00h.m_vendorRev);
            uint16_t wavelength = (uint16_t)((uint16_t)m_upperMemory00h.m_waveLength[0] << 8 | m_upperMemory00h.m_waveLength[1]);
            printf("4x Wavelength:%d nm\n",(wavelength/20));
            printf("4x Vendor SN:%s\n",m_upperMemory00h.m_vendorSN);
        }
        
        if(init12xFlag == DEV_SUCCESS) {
            refresh_qsfp_12x_tx_cache(&m_x12tx);
            refresh_qsfp_12x_rx_cache(&m_x12rx);
            sleep(1);
            refresh_qsfp_12x_tx_upperMemory();
            refresh_qsfp_12x_rx_upperMemory();


            memcpy(m_txdata,(uint8_t *)&m_x12tx,128);
            memcpy(&m_txdata[128],m_qsfp_12x_tx_upper[1],128);
            printf("12路光模块TX高位01H页数据\n");
            qlog_hexdump("tx",16,m_txdata,sizeof(m_txdata));
            memcpy(m_rxdata,(uint8_t *)&m_x12rx,128);
            memcpy(&m_rxdata[128],m_qsfp_12x_rx_upper[1],128);
            printf("12路光模块RX高位01H页数据\n");
            qlog_hexdump("rx",16,m_rxdata,sizeof(m_rxdata));
        }
        sleep(1);
        

    }
    return ret;
}